package scjp.preparation.concurrency;

import java.util.concurrent.Semaphore;
//This class simulates a situation where an ATM room has only two ATM machines
//and five people are waiting to access the machine. Since only one person can access
//an ATM machine at a given time, others wait for their turn
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class ATMRoom {
	public static void main(String[] args) {
		Lock machine = new ReentrantLock();
		// assume that only two ATM machines are available in the ATM room
//		Semaphore machines = new Semaphore(1);
		// list of people waiting to access the machine
		new Person(machine, "Mickey");
		new Person(machine, "Donald");
		new Person(machine, "Tom");
		new Person(machine, "Jerry");
		new Person(machine, "Casper");
	}
}

// Each Person is an independent thread; but their access to the common resource
// (two ATM machines in the ATM machine room in this case) needs to be
// synchronized.
class Person extends Thread {
//	private Semaphore machines;
	Lock machine;

	public Person(Lock machine, String name) {
		this.machine = machine;
		this.setName(name);
		this.start();
	}

	public void run() {
		try {
			System.out.println(getName() + " waiting to access an ATM machine");
			machine.lock();
			System.out.println(getName() + " is accessing an ATM machine");
			Thread.sleep(3000); // simulate the time required for withdrawing
			System.out.println(getName() + " is done using the ATM machine");
		} catch (InterruptedException ie) {
			System.err.println(ie);
		}
		finally {
			machine.unlock();
		}
	}
}